class Animal(object):
    def __init__(self, name):
        self.name = name

    def noice(self):
        print(f"{self.name} is yealling") # 这样可以直接打印出
        # return f"{self.name} is yealling"   # 这样需要一个接收,再被打印

class Flyable(object):
    def __init__(self,name):
        self.name = name
    def fling(self):
        print(f"{self.name} can fly")


class Dog(Animal):
    def __init__(self, name, age):
        super().__init__(name)
        self.age = age

# Dog 是继承 展示
# Cat 是继承加重写 的展示

class Cat(Animal):
    def __init__(self, name, age):
        super().__init__(name)  # 调用父类构造函数
        self.age = age

    def noice(self):  # 未写则调用父类的
        print(f"{self.name} loves yelling at night")
        return super().noice()

    def running(self):
        print(f"{self.name} is {self.age}, loves running")

# 多继承;一个类具有多个父类
class Bird(Animal,Flyable):
    def __init__(self, name):
        Animal.__init__(self, name)
        Flyable.__init__(self, name)
    def fling(self):
        print(f"{self.name} loves fling")
        return super().fling()
    def noice(self):
        print(f"{self.name} is yelling")


dog_demo = Dog("puppy", 2)
cat_demo = Cat("mimi", 3)
Bird_demo = Bird("gugu")


# dog_demo.noice()
# cat_demo.noice()
# cat_demo.running()
# Bird_demo.fling()
# Bird_demo.noice()


# 多态
## 它允许不同的子类对象调用相同的父类方法，但是实际调用并实现的是各自子类的方法，这样就可以实现不同的功能，提高代码的灵活性和可扩展性
## 多态的好处是当我们需要增加新的子类时，只需要继承父类并实现相应的方法即可，不需要修改父类的代码，这样就提高了代码的可扩展性和可维护性。

def animal_noice(animal : Animal):  # : Animal是一个类型注解; animal是参数; animal_noice是函数名
    print("多态==============")
    animal.noice() # 调用传入animal参数的noice方法

animal_noice(cat_demo)
animal_noice(dog_demo)
animal_noice(Bird_demo)

